﻿using SQLDeploy.Data.Deployment.Steps;
using SQLDeploy.Data.Internal;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Xml.Serialization;


namespace SQLDeploy.Data.Deployment
{
    [XmlRoot("Deployment")]
    public class Deployment : ValidationNotifier
    {
        private string _versionName;
        private bool _parellelExecution = false;
        private ObservableCollection<Step> _steps = new ObservableCollection<Step>();

        public string Version
        {
            get { return _versionName; }
            set
            {
                if (string.IsNullOrEmpty(value))
                    throw new ArgumentNullException("Version cannot be null or empty");
                if (_versionName == null ||
                    !Internal.Shared.Equals(_versionName, value))
                {
                    _versionName = value;
                    OnPropertyChanged("Version");
                }
            }
        }
        
        public bool ParellelExecution
        {
            get { return _parellelExecution; }
            set
            {
                if (_parellelExecution != value)
                {
                    _parellelExecution = value;

                }
            }
        }

        public ObservableCollection<Step> Steps
        {
            get 
            {
                //Make sure steps are always returned ordered by Id
                return (ObservableCollection<Step>)_steps.OrderBy(m => m.Id);
            }
        }

        public Step CreateStep()
        {
            return new Step(this);
        }

        public void addStep(Step newStep)
        {
            if (newStep.Id < 0)
            {
                newStep.Id = getNextStepId();
            }
            else
            {
                Step dupe = _steps.FirstOrDefault(i => i.Id == newStep.Id);
                if (dupe != null)
                    throw new ArgumentException("Attempt to create new step with existing Id of " + newStep.Id + " has failed.");
            }
            _steps.Add(newStep);
        }

        public void removeStep(int id)
        {
            Step item = _steps.FirstOrDefault(m => m.Id == id);
            if (item != null)
                _steps.Remove(item);
        }

        public void removeStep(Step step)
        {
            removeStep(step.Id);
        }

        protected internal int getNextStepId(){
            Step last = _steps.LastOrDefault();
            if (last == null)
                return 1;
            else
                return last.Id + 1;
        }

        public override bool performValidation()
        {
            bool allValid = true;
            foreach(Step step in Steps){
                if (!step.performValidation())
                    allValid = false;
            }
            return allValid;
        }
    
    }
}
